import 'package:bilibili/db/hi_cache.dart';
import 'package:bilibili/http/dao/login_dao.dart';
import 'package:bilibili/model/home_mo.dart';
import 'package:bilibili/model/video_model.dart';
import 'package:bilibili/navigator/bottom_navigator.dart';
import 'package:bilibili/navigator/hi_navigator.dart';
import 'package:bilibili/page/login_page.dart';
import 'package:bilibili/page/registration_page.dart';
import 'package:bilibili/page/video_detail_page.dart';
import 'package:bilibili/util/color.dart';
import 'package:bilibili/util/toast.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(BiliApp());
}

class BiliApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _BiliAppState();
  }
}

class _BiliAppState extends State<StatefulWidget> {
  BiliRouteDelegate _routeDlegate = BiliRouteDelegate();

  @override
  Widget build(BuildContext context) {
    ///FutureBuilder 允许你在异步操作完成之前显示一个占位符，并在操作完成后显示结果
    return FutureBuilder<HiCache>(
        future: HiCache.preInit(),
        builder: (BuildContext context, AsyncSnapshot<HiCache> snapshot) {
          var widget = snapshot.connectionState == ConnectionState.done
              ? Router(routerDelegate: _routeDlegate)
              : Scaffold(
                  body: Center(
                  child: CircularProgressIndicator(),
                ));
          return MaterialApp(
            home: widget,
            theme: ThemeData(primarySwatch: white),
          );
        });
  }
}

class BiliRouteDelegate extends RouterDelegate<BiliRoutePath>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin {
  @override
  final GlobalKey<NavigatorState> navigatorKey;

  BiliRouteDelegate() : navigatorKey = GlobalKey<NavigatorState>() {
    HiNavigator.getInstance().registerRouteJump(
        RouteJumpListener(onJumpTo: (RouteStatus routeStatus, {Map? args}) {
      _routeStatus = routeStatus;
      if (routeStatus == RouteStatus.detail) {
        videoMo = args?['videoMo'];
      }
      notifyListeners();
    }));
  }
  List<MaterialPage> pages = [];
  VideoMo? videoMo;

  RouteStatus _routeStatus = RouteStatus.home;
  bool get hasLogin => LoginDao.getBoardingPass() != null;

  RouteStatus get routeStatus {
    if (_routeStatus != RouteStatus.registration && !hasLogin) {
      return _routeStatus = RouteStatus.login;
    } else if (videoMo != null) {
      return _routeStatus = RouteStatus.detail;
    } else {
      return _routeStatus;
    }
  }

  @override
  Widget build(BuildContext context) {
    // 管理路由堆栈
    var index = getPageIndex(pages, routeStatus);
    List<MaterialPage> tempPages = pages;
    if (index != -1 && tempPages.isNotEmpty) {
      // 要打开的页面在栈中已存在，则将该页面和它上面的所有页面进行出栈
      // 具体规则可以根据需要进行调整，这里要求栈中只允许有一个同样的页面的实例
      tempPages = tempPages.sublist(0, index);
    }

    var page;
    if (routeStatus == RouteStatus.home) {
      pages.clear();
      page = pageWrap(BottomNavigator());
    } else if (routeStatus == RouteStatus.detail) {
      page = pageWrap(VideoDetailPage(
        videoMo: videoMo,
      ));
    } else if (routeStatus == RouteStatus.registration) {
      page = pageWrap(RegistrationPage());
    } else if (routeStatus == RouteStatus.login) {
      page = pageWrap(LoginPage());
    }

    tempPages = [...tempPages, page];
    // 跳转新页面时通知
    HiNavigator.getInstance().notifyListener(tempPages, pages);
    pages = tempPages;

    // 安卓物理返回键处理
    return WillPopScope(
        onWillPop: () async => !await navigatorKey.currentState!.maybePop(),
        child: Navigator(
          key: navigatorKey,
          pages: pages,
          onPopPage: (route, result) {
            // 回退老页面时
            if (route.settings is MaterialPage) {
              if ((route.settings as MaterialPage).child is LoginPage) {
                if (!hasLogin) {
                  showWarningToast("请先登录");
                  return false;
                }
              }
            }
            if (!route.didPop(result)) {
              return false;
            }
            var tempPages = [...pages];
            pages.removeLast();
            HiNavigator.getInstance().notifyListener(pages, tempPages);
            return true;
          },
          // onDidRemovePage: (page) {
          //   print(page);
          // },
        ));
  }

  @override
  Future<void> setNewRoutePath(BiliRoutePath configuration) async {}
}

class BiliRoutePath {
  final String location;
  BiliRoutePath.home() : location = "/";
  BiliRoutePath.detail() : location = "/detail";
}
